<?php
require_once("libs/controller.php");
require_once("modelos/keys.php");
require_once("modelos/peticion.php");

class HomeController extends Controller {
	
	protected $_DELIMITER = "||";
	protected $_KEY_TIME = 86400; // 1 day
	protected $_KEY_MAX_REQUESTS = 100;
	
	public function __construct() {
		$this->layout = "principal";	
		$this->pageTitle = "Home";	
	}
	
	public function index() {
	}
	
	
	/**
	 * Receives every request from a mobile app. Filter the request for valid key.
	 * @param v Base64 Text
	 */
	public function xRequest() {
		extract($_REQUEST);
		
		$is_guest = FALSE;
		
		// verify params
		if (!isset($v)) {
			//KO Error en base64
			$this->logger->error("Error en Base64");
			$this->returnKO(-1, DEFAULT_LANG);
		}
		
		//Decode Base64 text
		$this->logger->debug("Base64 text: $v");
		$string = base64_decode($v);
		$this->logger->debug("Decoded: $string");
		
		//split string: app_version, key, type, lang, ...
		$array = explode($this->_DELIMITER, $string);
		
		//verify splitted base64
		if (count($array) < 4) {
			//KO Error en base64
			$this->logger->error("Error en Base64");
			$this->returnKO(-1, DEFAULT_LANG);
		}
		
		
		//Verify App Version
		
		
		//Verify key
		$k = new Keys();
		$k->addCondition("clave", $array[1]);
		if ($k->doSelectAll()) {
			if ($k->next()) {
				$this->logger->debug("Key found!");
		
				//Expired key?
				$t = $k->getKeyTime();
				$actual = time();
				if ($actual > $t + $this->_KEY_TIME) {
					//KO Expired key
					//$this->logger->error("Key expired!");
					
					
				}
		
				//Already used key??
				if ($k->getValue("nro_peticiones") >= $this->_KEY_MAX_REQUESTS) {
					//KO Expired key
					$this->logger->error("Key already used!");
					$this->returnKO(-2, $array[3]);
				}
				
				//GUEST key?
				$is_guest = $k->isGuestUser();
				$this->logger->debug("Key is GUEST? " . ($is_guest ? "TRUE" : "FALSE"));

				
				//Incrementar numero peticiones realizadas para la key
				if ($k->setRequestNumber($array[1])) {
					$this->logger->debug("Num requests for $array[1] setted!");
				} else {
					$this->logger->error("ERROR setting Num requests for $array[1]!");
				}
			} else {
				//KO invalid key
				$this->logger->error("Invalid Key!");
				$this->returnKO(-5, $array[3]);
			}
		}
		
		
		//Verify request type & redirect
		$p = new Peticion();
		if ($p->doSelectOne(intval($array[2])) && $p->next()) {
			
			//Si es GUEST, se debe verificar si la peticion lo permite
			if ($is_guest && $p->getValue("permitir_guest") == "N") {
				//KO Debe iniciar sesion
				$this->returnKO(-7, $array[3]);
			}
			
			//Verificar si es la carga de fotos
			if (intval($array[2]) == 20) {
				$photo = $this->getPhotoName();
				if (is_null($photo) || count($photo) == 0) {
					$this->returnKO(-10, $array[3]);
				} else {
					array_push($array, $photo[0]);
					array_push($array, $photo[1]);
					array_push($array, $photo[2]);
				}
			}
			
		
			//Validar cantidad de parametros
			if ($p->getValue("parametros") == "" || is_null($p->getValue("parametros"))) {
				$parameters = array();
			} else {
				$parameters = explode(",", $p->getValue("parametros"));
			}
			$this->logger->debug("Params in request: " . (count($array)-4));
			$this->logger->debug("Params in BD: " . count($parameters));
			if (count($parameters) > count($array)-4) {
				$this->returnKO(-6, $array[3]);
			} 
			
			//Preparar la peticion
			$count = 4;
			$cadena = "";
			foreach ($parameters as $param) {
				//$_GET[$param] = $array[$count];
				$cadena = $cadena . $param . "=" . urlencode($array[$count]) . "&"; 
				
				$count++;
			}
			
			//Agregar otros campos
			//$_GET["lang"] = $array[3];
			//$_GET["id"] = $k->getIdUser();
			$cadena = $cadena . "lang=" . $array[3] . "&id=" . $k->getIdUser() . "&user_type=" . $k->getUserType();
						
			//Redirect!
			$cadena = APP_URL . $p->getValue("metodo") . "?$cadena";
			$this->logger->debug("Redirect to: " . $cadena);
			$this->redirect($cadena, TRUE);
			
		} else {
			//KO peticion invalida
			$this->returnKO(-3, $array[3]);
		}
		
	}
	
	protected function getPhotoName() {
		
		// Undefined | Multiple Files | $_FILES Corruption Attack
		// If this request falls under any of them, treat it invalid.
		if (!isset($_FILES['photo']['error']) || is_array($_FILES['photo']['error'])) {
			$this->logger->debug("Upload error: Invalid parameters.");
			return null;
		}
		
		// Check $_FILES['photo']['error'] value.
		switch ($_FILES['photo']['error']) {
			case UPLOAD_ERR_OK:
				break;
			case UPLOAD_ERR_NO_FILE:
				$this->logger->debug("Upload error: No file sent.");
				return null;
			case UPLOAD_ERR_INI_SIZE:
			case UPLOAD_ERR_FORM_SIZE:
				$this->logger->debug("Upload error: Exceeded filesize limit.");
				return null;
			default:
				$this->logger->debug("Upload error: Unknown errors.");
				return null;
		}
		
		
		$this->logger->debug("File name: " . $_FILES['photo']['name']);
		$this->logger->debug("File type: " . $_FILES['photo']['type']);
		$this->logger->debug("File size: " . $_FILES['photo']['size']);
		$this->logger->debug("File tmp : " . $_FILES['photo']['tmp_name']);
		
		// You should also check filesize here.
		if ($_FILES['photo']['size'] > 8048576) {
			$this->logger->debug("Upload error: Exceeded filesize limit.");
			return null;
		}
		
		
		// DO NOT TRUST $_FILES['photo']['mime'] VALUE !!
		// Check MIME Type by yourself.
		if (false === $ext = array_search(
				$_FILES['photo']['type'],
				array(
						'jpg' => 'image/jpeg',
						'png' => 'image/png',
						'gif' => 'image/gif',
				),
				true
		)) {
			$this->logger->debug("Upload error: Invalid file format.");
			return null;
		}
		
		// You should name it uniquely.
		// DO NOT USE $_FILES['upfile']['name'] WITHOUT ANY VALIDATION !!
		// On this example, obtain safe unique name from its binary data.
		$name = sprintf('./tmp/%s.%s',
						sha1_file($_FILES['photo']['tmp_name']),
						$ext
				);
		if (!move_uploaded_file(
				$_FILES['photo']['tmp_name'],
				$name
		)) {
			$this->logger->debug("Upload error: Failed to move uploaded file.");
			return null;
		}
		
		//GO GO
		$return = array();
		array_push($return, $name);
		array_push($return, $_FILES['photo']['name']);
		array_push($return, $_FILES['photo']['type']);
		
		return $return;
		
	}

}

?>